package com.beta.cat.aop;

import com.beta.cat.utils.LogCollectionUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;

/**
 * 接口切面基类
 *
 * @author kevin_zhang
 */
public class ApiBaseAspect {

    /**
     * 接口执行切面方法
     *
     * @param joinPoint
     * @param request
     * @param isPrintResult
     * @return
     * @throws Throwable
     */
    public Object around(ProceedingJoinPoint joinPoint, HttpServletRequest request, boolean isPrintResult) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Object restObj = null;
        try {
            restObj = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            restObj = (throwable.getStackTrace().length > 0) ? throwable.getStackTrace()[0] : throwable.getStackTrace();
            throw throwable;
        } finally {
            long endTime = System.currentTimeMillis();
            LogCollectionUtil.logCollection(request, restObj, beginTime, endTime, isPrintResult);
        }
        return restObj;
    }

    /**
     * RPC接口执行切面方法
     *
     * @param joinPoint
     * @param isPrintResult
     * @return
     * @throws Throwable
     */
    public Object aroundRpc(ProceedingJoinPoint joinPoint, boolean isPrintResult) throws Throwable {
        long beginTime = System.currentTimeMillis();
        Signature signature = joinPoint.getSignature();
        String functionName = signature.toLongString();
        functionName = functionName.substring(functionName.lastIndexOf(" ")).trim();
        functionName = functionName.split("\\(")[0].trim();
        LinkedHashMap paramMap = new LinkedHashMap();
        if ((signature instanceof MethodSignature)) {
            String[] paramsName = ((MethodSignature) signature).getParameterNames();
            Object[] paramsValue = joinPoint.getArgs();
            for (int i = 0; i < paramsName.length; i++) {
                paramMap.put(paramsName[i], paramsValue[i]);
            }
        }

        Object restObj = null;
        try {
            restObj = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            restObj = (throwable.getStackTrace().length > 0) ? throwable.getStackTrace()[0] : throwable.getStackTrace();
            throw throwable;
        } finally {
            long endTime = System.currentTimeMillis();
            LogCollectionUtil.rpcLogCollection(functionName, paramMap, restObj, beginTime, endTime, isPrintResult);
        }
        return restObj;
    }
}
